/*
 *	WARN  :  THIS BACKEND CODE IS AUTO GENERATE, ALL RIGHTS RESERVED.
 *	AUTHOR:  ZhaoChunPing
 *	EMAIL :  forxy@126.com
 *	DATE  :  2022.1
 */

#include <stdint.h>
#include <stdlib.h>
#include "pkcs11.h"
#include "msg_fmt.h"
#include "auto_inner_pkcs11.h"

void	C_LoginUser_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_USER_TYPE userType;
	CK_UTF8CHAR_PTR pPin;
	CK_ULONG ulPinLen;
	CK_UTF8CHAR_PTR pUsername;
	CK_ULONG ulUsernameLen;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_USER_TYPE_unpack(&p, &userType);
	DATA_unpack_nocopy(&p, &pPin, &ulPinLen);
	DATA_unpack_nocopy(&p, &pUsername, &ulUsernameLen);
	result = C_LoginUser_inner(ctx, userType, pPin, ulPinLen, pUsername, ulUsernameLen);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_Logout_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;

	MSG_DECODE_INIT(in, &p, NULL);
	result = C_Logout_inner(ctx);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_EncryptInit_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_MECHANISM pMechanism;
	CK_OBJECT_HANDLE hKey;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_MECHANISM_unpack(&p, &pMechanism);
	CK_OBJECT_HANDLE_unpack(&p, &hKey);
	result = C_EncryptInit_inner(ctx, &pMechanism, hKey);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_EncryptUpdate_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pPart;
	CK_ULONG ulPartLen;
	CK_BYTE_PTR pEncryptedPart;
	CK_ULONG pulEncryptedPartLen;

	MSG_DECODE_INIT(in, &p, NULL);
	DATA_unpack_nocopy(&p, &pPart, &ulPartLen);
	MSG_ENCODE_INIT(out, &p, result);
	pEncryptedPart = (CK_BYTE_PTR)(p + 2);
	result = C_EncryptUpdate_inner(ctx, pPart, ulPartLen, pEncryptedPart, &pulEncryptedPartLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pEncryptedPart, pulEncryptedPartLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_EncryptFinal_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pLastEncryptedPart;
	CK_ULONG pulLastEncryptedPartLen;

	MSG_DECODE_INIT(in, &p, NULL);
	MSG_ENCODE_INIT(out, &p, result);
	pLastEncryptedPart = (CK_BYTE_PTR)(p + 2);
	result = C_EncryptFinal_inner(ctx, pLastEncryptedPart, &pulLastEncryptedPartLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pLastEncryptedPart, pulLastEncryptedPartLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_Encrypt_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pData;
	CK_ULONG ulDataLen;
	CK_BYTE_PTR pEncryptedData;
	CK_ULONG pulEncryptedDataLen;

	MSG_DECODE_INIT(in, &p, NULL);
	DATA_unpack_nocopy(&p, &pData, &ulDataLen);
	MSG_ENCODE_INIT(out, &p, result);
	pEncryptedData = (CK_BYTE_PTR)(p + 2);
	result = C_Encrypt_inner(ctx, pData, ulDataLen, pEncryptedData, &pulEncryptedDataLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pEncryptedData, pulEncryptedDataLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_DecryptInit_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_MECHANISM pMechanism;
	CK_OBJECT_HANDLE hKey;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_MECHANISM_unpack(&p, &pMechanism);
	CK_OBJECT_HANDLE_unpack(&p, &hKey);
	result = C_DecryptInit_inner(ctx, &pMechanism, hKey);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_DecryptUpdate_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pEncryptedPart;
	CK_ULONG ulEncryptedPartLen;
	CK_BYTE_PTR pPart;
	CK_ULONG pulPartLen;

	MSG_DECODE_INIT(in, &p, NULL);
	DATA_unpack_nocopy(&p, &pEncryptedPart, &ulEncryptedPartLen);
	MSG_ENCODE_INIT(out, &p, result);
	pPart = (CK_BYTE_PTR)(p + 2);
	result = C_DecryptUpdate_inner(ctx, pEncryptedPart, ulEncryptedPartLen, pPart, &pulPartLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pPart, pulPartLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_DecryptFinal_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pLastPart;
	CK_ULONG pulLastPartLen;

	MSG_DECODE_INIT(in, &p, NULL);
	MSG_ENCODE_INIT(out, &p, result);
	pLastPart = (CK_BYTE_PTR)(p + 2);
	result = C_DecryptFinal_inner(ctx, pLastPart, &pulLastPartLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pLastPart, pulLastPartLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_Decrypt_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pEncryptedData;
	CK_ULONG ulEncryptedDataLen;
	CK_BYTE_PTR pData;
	CK_ULONG pulDataLen;

	MSG_DECODE_INIT(in, &p, NULL);
	DATA_unpack_nocopy(&p, &pEncryptedData, &ulEncryptedDataLen);
	MSG_ENCODE_INIT(out, &p, result);
	pData = (CK_BYTE_PTR)(p + 2);
	result = C_Decrypt_inner(ctx, pEncryptedData, ulEncryptedDataLen, pData, &pulDataLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pData, pulDataLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_DigestInit_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_MECHANISM pMechanism;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_MECHANISM_unpack(&p, &pMechanism);
	result = C_DigestInit_inner(ctx, &pMechanism);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_DigestUpdate_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pPart;
	CK_ULONG ulPartLen;

	MSG_DECODE_INIT(in, &p, NULL);
	DATA_unpack_nocopy(&p, &pPart, &ulPartLen);
	result = C_DigestUpdate_inner(ctx, pPart, ulPartLen);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_DigestFinal_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pDigest;
	CK_ULONG pulDigestLen;

	MSG_DECODE_INIT(in, &p, NULL);
	MSG_ENCODE_INIT(out, &p, result);
	pDigest = (CK_BYTE_PTR)(p + 2);
	result = C_DigestFinal_inner(ctx, pDigest, &pulDigestLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pDigest, pulDigestLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_Digest_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pData;
	CK_ULONG ulDataLen;
	CK_BYTE_PTR pDigest;
	CK_ULONG pulDigestLen;

	MSG_DECODE_INIT(in, &p, NULL);
	DATA_unpack_nocopy(&p, &pData, &ulDataLen);
	MSG_ENCODE_INIT(out, &p, result);
	pDigest = (CK_BYTE_PTR)(p + 2);
	result = C_Digest_inner(ctx, pData, ulDataLen, pDigest, &pulDigestLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pDigest, pulDigestLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_Sign_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pData;
	CK_ULONG ulDataLen;
	CK_BYTE_PTR pSignature;
	CK_ULONG pulSignatureLen;

	MSG_DECODE_INIT(in, &p, NULL);
	DATA_unpack_nocopy(&p, &pData, &ulDataLen);
	MSG_ENCODE_INIT(out, &p, result);
	pSignature = (CK_BYTE_PTR)(p + 2);
	result = C_Sign_inner(ctx, pData, ulDataLen, pSignature, &pulSignatureLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pSignature, pulSignatureLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_Verify_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pData;
	CK_ULONG ulDataLen;
	CK_BYTE_PTR pSignature;
	CK_ULONG ulSignatureLen;

	MSG_DECODE_INIT(in, &p, NULL);
	DATA_unpack_nocopy(&p, &pData, &ulDataLen);
	DATA_unpack_nocopy(&p, &pSignature, &ulSignatureLen);
	result = C_Verify_inner(ctx, pData, ulDataLen, pSignature, ulSignatureLen);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_GenerateRandom_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_BYTE_PTR pRandomData;
	CK_ULONG ulRandomLen;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_ULONG_unpack(&p, &ulRandomLen);
	MSG_ENCODE_INIT(out, &p, result);
	pRandomData = (CK_BYTE_PTR)(p + 2);
	result = C_GenerateRandom_inner(ctx, pRandomData, ulRandomLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pRandomData, ulRandomLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_GenerateKey_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	int i;
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_MECHANISM pMechanism;
	CK_ATTRIBUTE_PTR pTemplate;
	CK_ULONG ulCount;
	CK_OBJECT_HANDLE phKey;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_MECHANISM_unpack(&p, &pMechanism);

	ARRAY_SIZE_unpack(&p, &ulCount);
	pTemplate = (CK_ATTRIBUTE_PTR)malloc(ulCount * sizeof(CK_ATTRIBUTE));
	for(i = 0; i < ulCount; i++)
	{
		CK_ATTRIBUTE_PTR one = pTemplate + i;
		CK_ATTRIBUTE_unpack(&p, one);
	}

	result = C_GenerateKey_inner(ctx, &pMechanism, pTemplate, ulCount, &phKey);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		CK_OBJECT_HANDLE_pack(phKey, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
	free(pTemplate);
}

void	C_GenerateKeyPair_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	int i;
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_MECHANISM pMechanism;
	CK_ATTRIBUTE_PTR pPublicKeyTemplate;
	CK_ULONG ulPublicKeyAttributeCount;
	CK_ATTRIBUTE_PTR pPrivateKeyTemplate;
	CK_ULONG ulPrivateKeyAttributeCount;
	CK_OBJECT_HANDLE phPublicKey;
	CK_OBJECT_HANDLE phPrivateKey;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_MECHANISM_unpack(&p, &pMechanism);

	ARRAY_SIZE_unpack(&p, &ulPublicKeyAttributeCount);
	pPublicKeyTemplate = (CK_ATTRIBUTE_PTR)malloc(ulPublicKeyAttributeCount * sizeof(CK_ATTRIBUTE));
	for(i = 0; i < ulPublicKeyAttributeCount; i++)
	{
		CK_ATTRIBUTE_PTR one = pPublicKeyTemplate + i;
		CK_ATTRIBUTE_unpack(&p, one);
	}


	ARRAY_SIZE_unpack(&p, &ulPrivateKeyAttributeCount);
	pPrivateKeyTemplate = (CK_ATTRIBUTE_PTR)malloc(ulPrivateKeyAttributeCount * sizeof(CK_ATTRIBUTE));
	for(i = 0; i < ulPrivateKeyAttributeCount; i++)
	{
		CK_ATTRIBUTE_PTR one = pPrivateKeyTemplate + i;
		CK_ATTRIBUTE_unpack(&p, one);
	}

	result = C_GenerateKeyPair_inner(ctx, &pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, &phPublicKey, &phPrivateKey);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		CK_OBJECT_HANDLE_pack(phPublicKey, &p);
		CK_OBJECT_HANDLE_pack(phPrivateKey, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
	free(pPublicKeyTemplate);
	free(pPrivateKeyTemplate);
}

void	C_CreateObject_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	int i;
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_ATTRIBUTE_PTR pTemplate;
	CK_ULONG ulCount;
	CK_OBJECT_HANDLE phObject;

	MSG_DECODE_INIT(in, &p, NULL);

	ARRAY_SIZE_unpack(&p, &ulCount);
	pTemplate = (CK_ATTRIBUTE_PTR)malloc(ulCount * sizeof(CK_ATTRIBUTE));
	for(i = 0; i < ulCount; i++)
	{
		CK_ATTRIBUTE_PTR one = pTemplate + i;
		CK_ATTRIBUTE_unpack(&p, one);
	}

	result = C_CreateObject_inner(ctx, pTemplate, ulCount, &phObject);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		CK_OBJECT_HANDLE_pack(phObject, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
	free(pTemplate);
}

void	C_DestroyObject_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_OBJECT_HANDLE hObject;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_OBJECT_HANDLE_unpack(&p, &hObject);
	result = C_DestroyObject_inner(ctx, hObject);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_FindObjectsInit_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	int i;
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_ATTRIBUTE_PTR pTemplate;
	CK_ULONG ulCount;

	MSG_DECODE_INIT(in, &p, NULL);

	ARRAY_SIZE_unpack(&p, &ulCount);
	pTemplate = (CK_ATTRIBUTE_PTR)malloc(ulCount * sizeof(CK_ATTRIBUTE));
	for(i = 0; i < ulCount; i++)
	{
		CK_ATTRIBUTE_PTR one = pTemplate + i;
		CK_ATTRIBUTE_unpack(&p, one);
	}

	result = C_FindObjectsInit_inner(ctx, pTemplate, ulCount);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
	free(pTemplate);
}

void	C_FindObjects_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	int i;
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_ULONG ulMaxObjectCount;
	CK_OBJECT_HANDLE_PTR phObject;
	CK_ULONG pulObjectCount;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_ULONG_unpack(&p, &ulMaxObjectCount);
	MSG_ENCODE_INIT(out, &p, result);
	phObject = (CK_OBJECT_HANDLE_PTR)(p + 2);
	result = C_FindObjects_inner(ctx, ulMaxObjectCount, phObject, &pulObjectCount);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		CK_OBJECT_HANDLE_ARRAY_pack(phObject, pulObjectCount, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_FindObjectsFinal_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;

	MSG_DECODE_INIT(in, &p, NULL);
	result = C_FindObjectsFinal_inner(ctx);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_GetAttributeValue_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	int i;
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_OBJECT_HANDLE hObject;
	CK_ATTRIBUTE_PTR pTemplate;
	CK_ULONG ulCount;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_OBJECT_HANDLE_unpack(&p, &hObject);

	ARRAY_SIZE_unpack(&p, &ulCount);
	pTemplate = (CK_ATTRIBUTE_PTR)malloc(ulCount * sizeof(CK_ATTRIBUTE));
	for(i = 0; i < ulCount; i++)
	{
		CK_ATTRIBUTE_PTR one = pTemplate + i;
		CK_ATTRIBUTE_unpack(&p, one);
	}

	result = C_GetAttributeValue_inner(ctx, hObject, pTemplate, ulCount);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		CK_ATTRIBUTE_ARRAY_pack(pTemplate, ulCount, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
	free(pTemplate);
}

void	C_SetAttributeValue_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	int i;
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_OBJECT_HANDLE hObject;
	CK_ATTRIBUTE_PTR pTemplate;
	CK_ULONG ulCount;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_OBJECT_HANDLE_unpack(&p, &hObject);

	ARRAY_SIZE_unpack(&p, &ulCount);
	pTemplate = (CK_ATTRIBUTE_PTR)malloc(ulCount * sizeof(CK_ATTRIBUTE));
	for(i = 0; i < ulCount; i++)
	{
		CK_ATTRIBUTE_PTR one = pTemplate + i;
		CK_ATTRIBUTE_unpack(&p, one);
	}

	result = C_SetAttributeValue_inner(ctx, hObject, pTemplate, ulCount);
	MSG_ENCODE_INIT(out, &p, result);

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
	free(pTemplate);
}

void	C_WrapKey_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_MECHANISM pMechanism;
	CK_OBJECT_HANDLE hWrappingKey;
	CK_OBJECT_HANDLE hKey;
	CK_BYTE_PTR pWrappedKey;
	CK_ULONG pulWrappedKeyLen;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_MECHANISM_unpack(&p, &pMechanism);
	CK_OBJECT_HANDLE_unpack(&p, &hWrappingKey);
	CK_OBJECT_HANDLE_unpack(&p, &hKey);
	MSG_ENCODE_INIT(out, &p, result);
	pWrappedKey = (CK_BYTE_PTR)(p + 2);
	result = C_WrapKey_inner(ctx, &pMechanism, hWrappingKey, hKey, pWrappedKey, &pulWrappedKeyLen);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		DATA_pack_no_copy(pWrappedKey, pulWrappedKeyLen, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
}

void	C_UnwrapKey_backend(void *ctx, uint8_t *in, uint32_t inlen, uint8_t *out, uint32_t *outlen)
{
	int i;
	uint8_t *p;
	uint16_t len;
	CK_RV result = -1;
	CK_MECHANISM pMechanism;
	CK_OBJECT_HANDLE hUnwrappingKey;
	CK_BYTE_PTR pWrappedKey;
	CK_ULONG ulWrappedKeyLen;
	CK_ATTRIBUTE_PTR pTemplate;
	CK_ULONG ulAttributeCount;
	CK_OBJECT_HANDLE phKey;

	MSG_DECODE_INIT(in, &p, NULL);
	CK_MECHANISM_unpack(&p, &pMechanism);
	CK_OBJECT_HANDLE_unpack(&p, &hUnwrappingKey);
	DATA_unpack_nocopy(&p, &pWrappedKey, &ulWrappedKeyLen);

	ARRAY_SIZE_unpack(&p, &ulAttributeCount);
	pTemplate = (CK_ATTRIBUTE_PTR)malloc(ulAttributeCount * sizeof(CK_ATTRIBUTE));
	for(i = 0; i < ulAttributeCount; i++)
	{
		CK_ATTRIBUTE_PTR one = pTemplate + i;
		CK_ATTRIBUTE_unpack(&p, one);
	}

	result = C_UnwrapKey_inner(ctx, &pMechanism, hUnwrappingKey, pWrappedKey, ulWrappedKeyLen, pTemplate, ulAttributeCount, &phKey);
	MSG_ENCODE_INIT(out, &p, result);
	if(result == CKR_OK)
	{
		CK_OBJECT_HANDLE_pack(phKey, &p);
	}

	len = p - out - 2;
	*(uint16_t *)out = htons(len);
	(*outlen) = len + 2;
	free(pTemplate);
}

